

#include "audio_renderer.h"
#include "sample_callback.h"
#include "av_codec_sample_log.h"

AudioRenderer::~AudioRenderer()
{
    AudioRendererRelease();
}

// 带返回值的写入数据函数
static OH_AudioData_Callback_Result OnWriteDataCallbackWithValidData(OH_AudioRenderer *renderer, void *userData,
                                                                     void *buffer, int32_t bufferLen)
{
    (void)renderer;
    CodecUserData *codecUserData = static_cast<CodecUserData *>(userData);
    if (codecUserData != nullptr) {
        std::unique_lock<std::mutex> lock(codecUserData->outputMutex_);
        OH_AudioData_Callback_Result ret = AUDIO_DATA_CALLBACK_RESULT_VALID;
        if (!codecUserData->ReadCache(buffer, bufferLen)) {
            ret = AUDIO_DATA_CALLBACK_RESULT_INVALID;
        }
        AVCODEC_SAMPLE_LOGD("render BufferLength:%{public}d Out buffer count: %{public}u, renderQueue.size: %{public}u",
                            bufferLen, codecUserData->outputFrameCount_, codecUserData->remainlen_);
        if (codecUserData->remainlen_ < bufferLen) {
            codecUserData->renderCond.notify_all();
        }
        return ret;
    }
    return AUDIO_DATA_CALLBACK_RESULT_INVALID;
}

// 自定义写入数据函数
static int32_t OnRenderWriteData(OH_AudioRenderer *renderer, void *userData, void *buffer, int32_t length)
{
    (void)renderer;
    (void)length;
    return 0;
}

// 自定义音频流事件函数
static int32_t OnRenderStreamEvent(OH_AudioRenderer *renderer, void *userData, OH_AudioStream_Event event)
{
    (void)renderer;
    (void)userData;
    (void)event;
    // 根据event表示的音频流事件信息，更新播放器状态和界面
    return 0;
}

// 自定义音频中断事件函数
static int32_t OnRenderInterruptEvent(OH_AudioRenderer *renderer, void *userData, OH_AudioInterrupt_ForceType type,
                                      OH_AudioInterrupt_Hint hint)
{
    (void)renderer;
    (void)userData;
    (void)type;
    (void)hint;
    // 根据type和hint表示的音频中断信息，更新播放器状态和界面
    return 0;
}

// 自定义异常回调函数
static int32_t OnRenderError(OH_AudioRenderer *renderer, void *userData, OH_AudioStream_Result error)
{
    (void)renderer;
    (void)userData;
    (void)error;
    AVCODEC_SAMPLE_LOGE("OnRenderError");
    // 根据error表示的音频异常信息，做出相应的处理
    return 0;
}

void AudioRenderer::AudioRendererInit(SampleInfo &sampleInfo, CodecUserData *audioDecContext)
{
    AudioRendererRelease();

    OH_AudioStreamBuilder_Create(&builder_, AUDIOSTREAM_TYPE_RENDERER);
    OH_AudioStreamBuilder_SetLatencyMode(builder_, AUDIOSTREAM_LATENCY_MODE_NORMAL);
    // 设置音频采样率
    OH_AudioStreamBuilder_SetSamplingRate(builder_, sampleInfo.audioSampleRate);
    // 设置音频声道
    OH_AudioStreamBuilder_SetChannelCount(builder_, sampleInfo.audioChannelCount);
    // 设置音频采样格式
    OH_AudioStreamBuilder_SetSampleFormat(builder_, AUDIOSTREAM_SAMPLE_S16LE);
    // 设置音频流的编码类型
    OH_AudioStreamBuilder_SetEncodingType(builder_, AUDIOSTREAM_ENCODING_TYPE_RAW);
    // 设置输出音频流的工作场景
    OH_AudioStreamBuilder_SetRendererInfo(builder_, AUDIOSTREAM_USAGE_MUSIC);
    AVCODEC_SAMPLE_LOGW("Init audioSampleRate: %{public}d, ChannelCount: %{public}d", sampleInfo.audioSampleRate,
                        sampleInfo.audioChannelCount);

    // 配置回调函数
    OH_AudioRenderer_Callbacks callbacks;
    //callbacks.OH_AudioRenderer_OnWriteData = OnRenderWriteData;
    callbacks.OH_AudioRenderer_OnWriteData = nullptr;
    callbacks.OH_AudioRenderer_OnStreamEvent = OnRenderStreamEvent;
    callbacks.OH_AudioRenderer_OnInterruptEvent = OnRenderInterruptEvent;
    callbacks.OH_AudioRenderer_OnError = OnRenderError;
    // 设置输出音频流的回调
    OH_AudioStream_Result ret2 = OH_AudioStreamBuilder_SetRendererCallback(builder_, callbacks, nullptr);

    // 配置带返回值的写回调函数
    OH_AudioRenderer_OnWriteDataCallback callback = OnWriteDataCallbackWithValidData;
    OH_AudioStream_Result ret1 =
        OH_AudioStreamBuilder_SetRendererWriteDataCallback(builder_, callback, audioDecContext);

    OH_AudioStreamBuilder_GenerateRenderer(builder_, &audioRenderer_);
}

void AudioRenderer::AudioRendererStart()
{
    // 开启音频播放
    if (audioRenderer_ != nullptr) {
        OH_AudioRenderer_Start(audioRenderer_);
    }
}

void AudioRenderer::AudioRendererRelease()
{
    if (audioRenderer_ != nullptr) {
        OH_AudioRenderer_Stop(audioRenderer_);
        OH_AudioRenderer_Release(audioRenderer_);
        audioRenderer_ = nullptr;
    }
    if (builder_ != nullptr) {
        OH_AudioStreamBuilder_Destroy(builder_);
        builder_ = nullptr;
    }
}

OH_AudioStream_Result AudioRenderer::GetTimestamp(clockid_t clockId, int64_t *framePosition, int64_t *timestamp)
{
    return OH_AudioRenderer_GetTimestamp(audioRenderer_, CLOCK_MONOTONIC, framePosition, timestamp);
}